package com.ym.controller.admin;

import com.qiniu.util.Auth;
import com.ym.common.utils.ServletUtil;
import com.ym.core.annotation.Log;
import com.ym.core.config.ConfigCenterProperties;
import com.ym.core.config.FileTableConfig;
import com.ym.core.config.QiNiuYunConfig;
import com.ym.core.domain.APIResponse;
import com.ym.core.domain.BaseController;
import com.ym.core.shiro.ShiroUtil;
import com.ym.core.utils.qiniu.QNKeyEnum;
import com.ym.core.utils.qiniu.QNKeyUtil;
import com.ym.core.utils.qiniu.QiNiuUploadUtil;
import com.ym.medical.domain.entity.FileInforEntity;
import com.ym.medical.enums.FileTypeEnum;
import com.ym.medical.service.IFileInforSV;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import java.util.HashMap;
import java.util.Map;

/**
 * 文件信息Controller
 *
 * @author ym
 * @date 2020-08-17
 */
@Api(tags = "admin-文件信息")
@RestController
@Validated
@RequestMapping(value = "/sys/file")
@Slf4j
public class FileInforController extends BaseController {

	@Autowired
	private IFileInforSV fileInforSV;

	@Autowired
	private ConfigCenterProperties configCenterProperties;

	@Autowired
	private FileTableConfig fileTableConfig;

	@Value("${spring.profiles.active}")
	private String profile;

	@Log(printBody = false)
	@ApiOperation("上传附件")
	@PostMapping("/uploadFile")
	@ResponseBody
	public APIResponse<Map<String, Object>> uploadFile(
			@ApiParam(name = "file", value = "文件") MultipartFile file,
			@NotNull @ApiParam(name = "fileType", value = "文件类型(DOC/IMG/REC/VIDEO)") FileTypeEnum fileType,
			@ApiParam(name = "table", value = "表名") String table,
			@ApiParam(name = "filed", value = "字段名") String filed,
			@ApiParam(name = "remark", value = "备注") String remark
	) {
		String key = fileInforSV.uploadFile(file, fileType, table, filed, remark, ShiroUtil.getLoginId(true));
		Map<String, Object> result = new HashMap<>();
		result.put("id", key);
		result.put("systemType", profile);
		return successData(result);
	}

	@Log(printBody = false)
	@ApiOperation("七牛上传附件")
	@PostMapping("/qiniu/upload")
	@ResponseBody
	public ResponseEntity<Map<String, Object>> qiniuUpload(MultipartFile file) throws Exception {
		Map<String, Object> result = new HashMap<>();
		try {
			String key = fileInforSV.uploadFile(file, FileTypeEnum.IMG, "qiniu", "qiniu", "七牛组件附件上传", ShiroUtil.getLoginId(true));
			result.put("message", "请求成功");
			result.put("success", true);
			result.put("code", 200);
			result.put("data", configCenterProperties.getQiNiuYunConfig().getShowImageUrl() + key);
		} catch (Exception e) {
			result.put("message", "请求失败");
			result.put("success", true);
			result.put("code", 500);
		}
		return ResponseEntity.ok().body(result);
	}

	@Log(printBody = false)
	@ApiOperation("查询附件信息")
	@GetMapping("/getFileById")
	@ResponseBody
	public APIResponse<FileInforEntity> getFileById(@ApiParam(name = "id", value = "文件ID", required = true) @RequestParam String id) throws Exception {
		return successData(fileInforSV.selectByStringId(id));
	}

	@Log(printBody = false)
	@ApiOperation("下载附件")
	@GetMapping("/dwlFile")
	@ResponseBody
	public APIResponse dwlFile(
			@ApiParam(name = "id", value = "文件ID", required = true) @RequestParam String id,
			HttpServletResponse response
	) throws Exception {
		FileInforEntity fileInfor = fileInforSV.selectByStringId(id);
		if (fileInfor == null) {
			return failMsg("文件不存在！");
		}
		if (fileInfor != null) {
			String dwlUrl = fileInforSV.getShowUrlByFileType(fileInfor.getFileType());
			String fileName = ServletUtil.setFileDownloadHeader(fileInfor.getFileName());
			response.sendRedirect(dwlUrl + fileInfor.getId() + "?attname=" + fileName);
		}
		return null;
	}


	@Log(printBody = false)
	@ApiOperation("获取上传凭证")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "upType", value = "获取凭证的类型.01图片02语音03文档04视频", required = true, paramType = "path"),
	})
	@GetMapping(value = "/upToken")
	public APIResponse upToken(
			@RequestParam @Pattern(regexp = "01|02|03|04") String upType,
			@RequestParam String fileKey
	) {
		QNKeyEnum qnKeyEnum = null;
		switch (upType) {
			case "01":
				qnKeyEnum = QNKeyEnum.GENERAL_PICTURE_UPLOAD;
				break;
			case "02":
				qnKeyEnum = QNKeyEnum.GENERAL_REC_UPLOAD;
				break;
			case "03":
				qnKeyEnum = QNKeyEnum.GENERAL_DOC_UPLOAD;
				break;
			case "04":
				qnKeyEnum = QNKeyEnum.GENERAL_VIDEO_UPLOAD;
				break;
		}
		String key = QNKeyUtil.keyBuilder(qnKeyEnum, fileKey);
		String upToken2CallBack = QiNiuUploadUtil.getUpToken(key, qnKeyEnum, true);
		return successData(upToken2CallBack);
	}

	@Log
	@ApiOperation("七牛上传回调方法")
	@ResponseBody
	@PostMapping(value = "/up/callBack", consumes = MediaType.APPLICATION_JSON_VALUE)
	public APIResponse upCallBack(
			@RequestBody String upPutPolicyStr,
			@RequestHeader String Authorization
	) {
		log.info("来自七牛上传回调Authorization:{}", Authorization);
		if (StringUtils.isBlank(Authorization)) {
			return success();
		}
		// 鉴权是否来自七牛云
		QiNiuYunConfig qiNiuYunConfig = configCenterProperties.getQiNiuYunConfig();
		boolean ok = false;
		ok = (Authorization.indexOf(qiNiuYunConfig.getAccessKey()) > -1);
		ok = (Authorization.indexOf("QBox") > -1);
		Auth auth = Auth.create(qiNiuYunConfig.getAccessKey(), qiNiuYunConfig.getSecretKey());
		ok = auth.isValidCallback(Authorization, qiNiuYunConfig.getUpCallBackUrl(), upPutPolicyStr.getBytes(), MediaType.APPLICATION_JSON_VALUE);
		if (ok) {
			log.info("内容为：{}", upPutPolicyStr);
			fileInforSV.fileSaveCallBack(upPutPolicyStr);
		} else {
			log.info("未知七牛回调");
		}
		return success();
	}

	@Log()
	@ApiOperation("清理垃圾")
	@PostMapping(value = "/cleanUp")
	@ResponseBody
	public APIResponse cleanUp(@RequestParam String clean) {
		String cleanMark = "confirm";
		if (!cleanMark.equals(clean)) {
			Map<String, Object> result = new HashMap<>();
			result.put("tips", "请确认清理以下附件资源，并再次输出confirm清理?");
			result.put("content", fileTableConfig.getTables());
			return successData(result);
		}
		Map<String, Integer> result = fileInforSV.cleanUp(clean);
		return successData(result);
	}

	@Log()
	@ApiOperation("copy附件到目标环境")
	@PostMapping(value = "/copy")
	@ResponseBody
	public APIResponse copy(
			@RequestParam String tables,
			@RequestParam @Pattern(regexp = "dev|prod|test|local|sit|uat") String env
	) {
		Map<String, Integer> result = fileInforSV.copyFileToTargetEnv(tables, env);
		return successData(result);
	}

}
